const RETRY_COUNT = 3

const sleep = (time) => new Promise(resolve => setTimeout(resolve, time));

const response = async (token: string) => {
  await sleep(Math.floor(Math.random() * 3000));
  if (token) {
    return {
      statusCode: 200,
      body: JSON.stringify({
        message: Math.random().toString(16).slice(2),
      })
    }
  }
  throw new Error("401");
}



const getToken = async (time) => {
  await sleep(200)
  console.log(`第${RETRY_COUNT - time + 1}次获取token~`)
  if (Math.random() > 0.5) {
    throw new Error("401");
  }
  return '123456'
}

/**
 * 请求重试
 * @param {*} time 重试次数
 * @returns {Promise<Object>} Promise
 */
async function retryGetToken(time = 3) {
  try {
    return await getToken(time)
  } catch (error) {
    if (time === 0) {
      console.error(`${RETRY_COUNT}次重试都失败`);
      
      throw error
    } else {
      console.warn('获取token失败，正在重试...')
      return await retryGetToken(time - 1)
    }
  }
}


const getTokenTask = (() => {
  let promiseTask: Promise<string> | null
  let isFetching = false; // 添加锁机制
  
  return async () => {
    if (!promiseTask && !isFetching) {
      isFetching = true;
      promiseTask = retryGetToken(RETRY_COUNT).finally(() => {
        isFetching = false;
      });
    }
    try {
      const token = await promiseTask;
      return token;
    } catch (error) {
      promiseTask = null; // 重置任务以便后续重试
      throw error;
    }
  }
})()


const createGetDataTask = async () => {
  const token = await getTokenTask() as string
  const res = await response(token)
  console.log('成功获取数据', res)
}

createGetDataTask()
createGetDataTask()
createGetDataTask()
createGetDataTask()